<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\AgentConfig;
use App\Models\Enterprise;
use App\Models\YeepayBank;
use App\Models\YeepayDistrict;
use App\Services\AdaPayService;
use App\Services\ObsService;
use App\Services\YeepayService;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Arr;
use Vinlon\Laravel\LayAdmin\Exceptions\AdminException;
use ZipArchive;

class EnterpriseController extends Controller
{
    /** @var ObsService */
    private $obsService;

    public function __construct(ObsService $obsService)
    {
        $this->obsService = $obsService;
    }

    public function index(Request $request)
    {
        $enterprise = Enterprise::when(!empty($request->keyword), function ($q) use ($request) {
            $q->whereLike('name', '%' . $request->keyword . '%');
        })->with(['agent'])->orderByDesc('id');

        return paginate_result($enterprise);
    }

    /**
     * @throws AdminException
     */
    public function store(Request $request)
    {
        request()->validate([
            'name' => 'required',
            'licenceUrl' => 'required',
            'licenceNo' => 'required',
            'legalName' => 'required',
            'legalLicenceNo' => 'required',
            'legalLicenceFrontUrl' => 'required',
            'legalLicenceBackUrl' => 'required',
            'contactName' => 'required',
            'contactMobile' => 'required',
            'contactEmail' => 'required',
            'contactLicenceNo' => 'required',
            'province' => 'required',
            'city' => 'required',
            'district' => 'required',
            'address' => 'required',
            'bankCode' => 'required',
            'bankCardNo' => 'required',
            'agent_id' => 'nullable',
            'pay_channel' => 'required',
            'licenceNoExpires' => 'required',
            'legalLicenceNoExpires' => 'required',
            'business_scope' => 'required',
        ]);

        /** @var Enterprise $enterprise */
        $enterprise = get_entity(Enterprise::class);
        $data = $request->all();
        if (!$enterprise->id) {
            $data['requestNo'] = 'enterprise_reg_' . uniqid();
            $data['settlementDirection'] = 'BANKCARD';
            $data['bankAccountType'] = 'ENTERPRISE_ACCOUNT';
            $data['signName'] = $data['name'];
            $data['shortName'] = $data['name'];
            $data['legalLicenceType'] = 'ID_CARD';
            $data['servicePhone'] = $data['contactMobile'];
            $enterprise->fill($data);
        }
        $enterprise->save();
        if ('adapay' == $data['pay_channel']) {
            if (empty($data['agent_id'])) {
                throw new AdminException('支付通道为汇付天下，必须选择所属代理商');
            }

            $config = AgentConfig::query()->where('agent_id', $data['agent_id'])->pluck('config_value', 'config_key');

            if (empty(Arr::get($config, AgentConfig::ADAPAY_APP_ID, ''))) {
                throw new AdminException('请先配置汇付天下支付参数');
            }
            $adaPay = new AdaPayService($config);
            $data['attach_url'] = $this->createZipFile([
                Arr::get($data, 'licenceUrl'),
                Arr::get($data, 'legalLicenceFrontUrl'),
                Arr::get($data, 'legalLicenceBackUrl'),
            ]);

            try {
                $open_rep = $adaPay->corpMemberCreat($data);
            } catch (\Exception $e) {
                throw new AdminException($e->getMessage());
            }
        } else {
            $yeepay = new YeepayService();

            $data['licenceUrl'] = $yeepay->upload($data['licenceUrl']);
            $data['legalLicenceFrontUrl'] = $yeepay->upload($data['legalLicenceFrontUrl']);
            $data['legalLicenceBackUrl'] = $yeepay->upload($data['legalLicenceBackUrl']);

            $open_rep = $yeepay->enterpriseRegister($data);
        }
        $enterprise->applicationTime = now();
        $enterprise->applicationStatus = $open_rep['applicationStatus'];
        $enterprise->code = $open_rep['merchantNo'];

        return $enterprise->save();
    }

    public function show($id)
    {
        $enterprise = Enterprise::query()->find($id);

        return $enterprise->toArray();
    }

    public function destroy($id)
    {
        Enterprise::destroy($id);
    }

    public function address(Request $request)
    {
        $level = $request->level;

        if (1 == $level) {
            $provinces = YeepayDistrict::select(['province_code', 'province_name'])->get();
            $address = $this->distinct($provinces, 'province');
        } elseif (2 == $level) {
            $citys = YeepayDistrict::where('province_code', $request->province_code)
                ->select(['city_code', 'city_name'])->get();

            $address = $address = $this->distinct($citys, 'city');
        } elseif (3 == $level) {
            $districts = YeepayDistrict::where('city_code', $request->city_code)
                ->select(['district_code', 'district_name'])->get();

            $address = $this->distinct($districts, 'district');
        }

        return $address;
    }

    public function banks()
    {
        return YeepayBank::select(['code', 'name'])->get();
    }

    public function distinct($arr, $field)
    {
        $address = [];
        $arr_flag = [];
        $field_code = $field . '_code';
        $field_name = $field . '_name';
        foreach ($arr as $k => $v) {
            if (in_array($v->{$field_code}, $arr_flag)) {
                continue;
            }
            $tmp = [$field_code => $v->{$field_code}, $field_name => $v->{$field_name}];
            $arr_flag[] = $v->{$field_code};
            $address[] = $tmp;
        }

        return $address;
    }

    private function createZipFile($fileUrls)
    {
        $zip = new ZipArchive();
        $zipFileName = uniqid() . '.zip';
        $zipFilePath = storage_path('app/' . $zipFileName);

        if (true === $zip->open($zipFilePath, ZipArchive::CREATE)) {
            foreach ($fileUrls as $fileUrl) {
                $fileName = basename($fileUrl);
                $fileContent = file_get_contents($fileUrl);
                $zip->addFromString($fileName, $fileContent);
            }
            $zip->close();
            // 创建一个 UploadedFile 对象
            $uploadedFile = new UploadedFile($zipFilePath, $zipFileName, null, null, true);
            $fileUrl = $this->obsService->upload('zip/' . uniqid(), $uploadedFile);
            unlink($zipFilePath);

            return $fileUrl;
        }

        throw new AdminException('压缩文件创建失败');
    }
}
